<?php
/**
 * @package mikrokosmos
 * mk script file created on 3-mar-2006
 * jaco_at_pixeldump_dot_org
 */

if(!class_exists("MKTagHeader")){ class MKTagHeader {}}


/**
 * button wrapper class
 * wraps both defineButton or defineButton2 tag
 * */
class MKButtonContainer extends MKTagHeader {

	// buttonID is an alias of itemID
	var $tagData = "";
	var $trackAsMenu = 0;
	var $actionOffset = 0;
	var $characters = array();
	var $bcActions = array();
	var $bs;					// buttonSound
	var $po;					// placeObject2
	var $linkage;				// linkage

	var $nodeName = "button";

	// the constructor
	function MKButtonContainer($tagData = "", $buttonID = 1){

		$this->tagData = $tagData;
		$this->itemID = $buttonID;
		$this->tagID = BUTTON2;

		if(strlen($tagData)){
			parent::MKTagHeader(substr($tagData, 0, 10));
			$this->get_button_data();
		}
		$this->po = new MKPlaceObject2("", $buttonID, $buttonID);
	}

	// almost alias of set/get tagID
	function set_type($type) { $this->tagID = $type; }
	function get_type() { return $this->tagID; }

	//
	function set_buttonID($buttonID) {
		$this->itemID = $buttonID;
		if(isset($this->bs)) $this->bs->set_buttonID($buttonID);
		$this->po->set_itemID($buttonID);
	}
	function get_buttonID() { return $this->itemID; }

	//
	function set_trackAsMenu($trackAsMenu) { $this->itemID = $trackAsMenu; }
	function get_trackAsMenu() { return $this->itemID; }

	//
	function set_actionOffset($actionOffset) { $this->actionOffset = $actionOffset; }
	function get_actionOffset() { return $this->actionOffset; }

	//
	function set_characters($characters) { $this->characters = $characters; }
	function get_characters() { return $this->characters; }

	//
	function set_bcActions($bcActions) { $this->bcActions = $bcActions; }
	function get_bcActions() { return $this->bcActions; }

	//
	function set_tagData($tagData) {
		$this->MKbutton2($tagData);
	}


	// build buttonSound state
	// soundID: sound for the relevant event
	// eventType: one of these: ROLL_OUT, ROLL_OVER, PRESS, RELEASE
	// soundInfo: a soundInfo object
	function set_sound_event($soundID  = 1, $eventType = ROLL_OVER, $soundInfo = ""){
		if(!isset($this->bs)) $this->bs = new MKButtonSound("", $this->itemID);
		$this->bs->set_sound_event($soundID, $eventType, $soundInfo);
	}

	//
	function set_placeObject2($po){ $this->po = $po; }
	function get_placeObject2(){ return $this->po; }

	//
	function get_placeDepth(){ return $this->po->get_depth(); }

	// set translation data for placeObject2
	function move($x, $y, $isChange = false){
		$this->po->set_position($x, $y, $isChange);
	}

	// set scale data for placeObject2
	function scale($scaleX, $scaleY, $isChange = false){
		$this->po->set_scale($scaleX, $scaleY, $isChange);
	}

	// set rotation data for placeObject2
	function rotate($rotation, $isChange = false){
		$this->po->set_rotation($rotation, $isChange);
	}

	//
	function add_character($itemID = 1, $depth = 1, $state, $placeMatrix = "", $colorTransform = ""){

		$brIdx = count($this->characters);
		$brData = array();
		$brData["buttonType"] = BUTTON2;
		$brData["characterID"] = $itemID;
		$brData["placeDepth"] = $depth;
		$brFlags = array("stateHitTest", "stateDown", "stateOver", "stateUp");
		$stateStr = get_binData_string($state);
		$stateStr = substr($stateStr, 4);

		for($i = 0; $i < 4; $i++)
			if($stateStr == "1") $brData[$brFlags[$i]] = 1;

		$this->characters[$brIdx] = new MKButtonRecord("", $brData);
		if(strlen($placeMatrix)) $this->characters[$brIdx]->set_placeMatrix($placeMatrix);
		if(strlen($colorTransform)) $this->characters[$brIdx]->set_colorTransform($colorTransform);
	}

	// alias of add_character
	function add_buttonRecord($itemID = 1, $depth = 1, $state, $placeMatrix = "", $colorTransform = ""){
		$this->add_character($itemID, $depth, $state, $placeMatrix, $colorTransform);
	}

	// takes a valid mk class (shape, mc, etc.)
	// state is mandatory, it must contain one of these values
	// hit, down, over, up
	function build_button_state($obj, $state){

		if(strpos(strtolower($state), "hit") !== false) $state = "stateHitTest";
		else $state = "state" .ucfirst($state);

		$br = new MKButtonRecord();
		$br->build_from_object($obj, $state);
		$this->characters[] = $br;

		return $this->update_tagData();
	}

	// build characters from array
	// each item must be a valid MKclass with placeObject handler
	// states is an optional param, you may specify what states you prefer
	// from HitArea, down, over, up
	// if you give an array of object less than four item count
	// and you don't specify states array, it will build button
	// following the order: Hit, Down, Over, Up
	function build_from_array($objAr = array(), $states = array()){

		if(!count($objAr)) return false;
		if(!count($states)) $states = array("HitTest", "Down", "Over", "Up");

		$oCount = count($objAr);
		$maxCount = min($oCount, 4);

		for($i = 0; $i < $maxCount; $i++){

			if(strpos(strtolower($states[$i]), "hit") !== false) $state = "stateHitTest";
			else $state = "state" .ucfirst($states[$i]);

			$obj = $objAr[$i];
			$br = new MKButtonRecord();
			$br->build_from_object($obj, $state);
			$this->characters[] = $br;
		}

		return $this->update_tagData();
	}

	//
	function update_linkage($linkageName = ""){
		if(!isset($this->linkage)) $this->linkage = new MKExportAssets();
		$this->linkage->update_asset($this->itemID, $linkageName, 0);

		// prevent empty linkage name
		// in case it provides an automated generated name
		$linkageRef = $this->linkage->get_assetAt(0);
		if(!strlen($linkageRef["name"])) $linkageName = "buttonID" .$this->itemID;
		$this->linkage->update_asset($this->itemID, $linkageName, 0);

		return $this->linkage->update_tagData();
	}

	//
	function set_linkage_name($linkageName = ""){
		return $this->update_linkage($linkageName);
	}


	//
	function set_button_data($bd = array()){

		if(count($bd)){
			$this->get_sound_data($bd);
		}
		else {
			$bd = $this->fetch_assoc();
		}

		$this->tagData = write_defineButton_data($bd);
		return $this->tagData;
	}

	//
	function get_button_data($bd = array()){

		if(!count($bd)) $bd = read_defineButton_data($this->tagData);

		$this->trackAsMenu = $bd["trackAsMenu"];
		$this->actionOffset = $bd["actionOffset"];
		$chLength = strlen($bd["chBuf"]);
		$ofst = 0;
		$k = 0;
		do {
			$chIdx = count($this->characters);
			$this->characters[$chIdx] = new MKButtonRecord(substr($bd["chBuf"], $ofst), array(), $this->tagID);
			$ofst += $this->characters[$chIdx]->get_length();
		} while ($ofst < $chLength);

		if($this->actionOffset){

			$ttLength = $this->tagSL + $this->tagLength;
			$ofst = $this->tagSL + 3 + $this->actionOffset;
			//$bta = substr($this->tagData, $ofst);

			do {

				$actionSize = ui16dec(substr($this->tagData, $ofst, 2));
				// last buttonCondAction has actionSize to 0
				// so we have to compute each time the right amount of data to read
				$aSize = $actionSize ? $actionSize : $ttLength - $ofst;
				$bcBuf = substr($this->tagData, $ofst, $aSize);
				$this->bcActions[] = new MKButtonCondAction($bcBuf);
				$ofst += $aSize;
			} while ($ofst < $ttLength);
		}
	}

	//
	function fetch_assoc(){

		$bd = array();

		$bd["type"] = $this->tagID;
		$bd["tagID"] = $this->tagID;
		$bd["itemID"] = $this->itemID;
		$bd["trackAsMenu"] = $this->trackAsMenu;
		$bd["actionOffset"] = $this->actionOffset;
		$bd["characters"] = array();

		foreach($this->characters as $c){
			$bd["characters"][] = $c->fetch_assoc();
 		}

		/* TODO  put buttonCondActions data as buffer */
		// $bd["bcaBuf"] = substr();

		return $bd;
	}

	//
	function fetch_xml($includeHeader = true, $tabLevel = 0, $includeHexData = false, $nodeName = "button"){


		$xmlStr = $includeHeader ? XML_HEADER : "";
		$pfx = get_xml_indent_row(++$tabLevel);

		$xmlStr .= $pfx ."<" .$nodeName ." ";

		$xmlStr .= "id=\"";
		$xmlStr .= $this->itemID ."\" ";

		if($this->tagID == BUTTON2)$xmlStr .= "buttonType=\"advanced\" ";

		$xmlStr .= "tagSize=\"";
		$xmlStr .= strlen($this->tagData) ."\" ";

		if($this->trackAsMenu) $xmlStr .= "trackAsMenu=\"1\" ";
		$xmlStr .= ">";

		$pfx = get_xml_indent_row(++$tabLevel);

		$xmlStr .= $pfx ."<TODO value=\"complete button definition\" />";
		$pfx = get_xml_indent_row(--$tabLevel);

		$xmlStr .= $pfx ."</" .$nodeName .">";
		return $xmlStr;
	}

	//
	function fetch_flasm($indentationLevel = 2){

		$il = $indentationLevel;
		$ilStr = str_repeat(" ", $il);
		$fStr = "\r\n" .$ilStr ."defineButton " .$this->itemID;

		foreach($this->bcActions as $bca)
			$fStr .= $bca->fetch_flasm($il + 2);

		$fStr .= "\r\n" .$ilStr ."end // of defineButton " .$this->itemID;
		$fStr .= "\r\n";
		return $fStr;
	}

	// returns buttonSound tagData
	function update_buttonSound_tagData() { return $this->bs->update_tagData(); }

	// returns placeObject2 tagData
	function update_place_tagData($replacingDepth = -1){
		return $this->po->update_tagData($replacingDepth);
	}

	// returns linkage tagData
	function update_linkage_tagData(){
		$this->update_linkage();
		return $this->linkage->update_tagData();
	}

	//
	function update_tagData(){ return $this->set_button_data(); }
}


/**
 * BUTTONRECORD
 */
class MKButtonRecord {

	var $buf = "";
	var $buttonType = BUTTON2;
	var $reserved = 0;		// UB[2] Reserved bits; always 0
	var $hasBlendMode = 0;	// UB[1] 0 = No blend mode
							// 1 = Has blend mode (SWF 8 and later only)
	var $hasFilterList = 0;	// UB[1] 0 = No filter list
							// 1 = Has filter list (SWF 8 and later only)
	var $stateHitTest = 0;	// UB[1] Present in hit test state
	var $stateDown = 0; 	// UB[1] Present in down state
	var $stateOver = 0;		// UB[1] Present in over state
	var $stateUp = 0;		// UB[1] Present in up state
	var $characterID = 1;	// UI16 ID of character to place
	var $placeDepth;		// UI16 Depth at which to place character
	var $placeMatrix;		// MATRIX Transformation matrix for character placement
	var $colorTransform;	// if within DefineButton2 CXFORMWITHALPHA
							// otherwise absent character color transform

	var $filterList;		// >= swf8 FILTERLIST object
	var $blendMode = 0;

	// the constructor
	function MKButtonRecord($buf = "", $brData = array(), $buttonType = BUTTON2){

		$this->buf = $buf;
		$this->buttonType = $buttonType;

		if(strlen($buf)){
			$this->get_buttonRecord_data();
		}
		else if(count($brData)){
			$this->set_buttonRecord_data($brData);
		}

		$this->placeMatrix = new MKMatrix();
		$this->colorTransform = new MKCxformWithAlpha();
	}

	//
	function set_blendMode($blendMode) { $this->blendMode = $blendMode; }
	function get_blendMode() { return $this->blendMode; }

	//
	function set_hasFilterList($hasFilterList) { $this->hasFilterList = $hasFilterList; }
	function get_hasFilterList() { return $this->hasFilterList; }

	//
	function set_buttonType($buttonType) { $this->buttonType = $buttonType; }
	function get_buttonType() { return $this->buttonType; }

	//
	function set_stateHitTest($stateHitTest) { $this->stateHitTest = $stateHitTest; }
	function get_stateHitTest() { return $this->stateHitTest; }

	//
	function set_stateDown($stateDown) { $this->stateDown = $stateDown; }
	function get_stateDown() { return $this->stateDown; }

	//
	function set_stateOver($stateOver) { $this->stateOver = $stateOver; }
	function get_stateOver() { return $this->stateOver; }

	//
	function set_stateUp($stateUp) { $this->stateUp = $stateUp; }
	function get_stateUp() { return $this->stateUp; }

	//
	function set_characterID($characterID) { $this->characterID = $characterID; }
	function get_characterID() { return $this->characterID; }

	//
	function set_placeDepth($placeDepth) { $this->placeDepth = $placeDepth; }
	function get_placeDepth() { return $this->placeDepth; }

	//
	function set_placeMatrix($placeMatrix) {

		if(is_array($placeMatrix)){
			$this->placeMatrix = new MKMatrix("", $placeMatrix);
		}
		else if(is_string($placeMatrix)){
			$this->placeMatrix = new MKMatrix($placeMatrix);
		}
		else if(get_class($placeMatrix) == "MKMatrix")
			$this->placeMatrix = $placeMatrix;
	}
	function get_placeMatrix() { return $this->placeMatrix; }

	//
	function set_colorTransform($colorTransform) {

		if(is_array($colorTransform)){
			$this->colorTransform = new MKCxformWithAlpha("", $colorTransform);
		}
		else if(is_string($colorTransform)){
			$this->colorTransform = new MKCxformWithAlpha($colorTransform);
		}
		else $this->colorTransform = $colorTransform;
	}
	function get_colorTransform() { return $this->colorTransform; }

	// object must be a valid and placeable
	function build_from_object($obj, $state){

		if($state == "stateHitTest") $this->stateHitTest = true;
		if($state == "stateDown") $this->stateDown = true;
		if($state == "stateOver") $this->stateOver = true;
		if($state == "stateUp") $this->stateUp = true;

		$this->characterID = $obj->get_itemID();
		$this->placeDepth = $obj->get_placeDepth();
		$po = $obj->get_placeObject2();
		$this->set_placeMatrix($po->get_matrix());
	}

	//
	function set_buttonRecord_data($brd = array()){

		if(!count($brd))
			$brd = $this->fetch_assoc();

		$this->buf = write_buttonRecord($brd, $this->buttonType);

		return $this->buf;
	}

	//
	function get_buttonRecord_data($brd = array()){

		if(!count($brd))
			$brd = read_buttonRecord_data($this->buf, $this->buttonType);

		$this->hasBlendMode	  = $brd["hasBlendMode"];
		$this->hasFilterList  = $brd["hasFilterList"];
		$this->stateHitTest	  = $brd["stateHitTest"];
		$this->stateDown	  = $brd["stateDown"];
		$this->stateOver	  = $brd["stateOver"];
		$this->stateUp		  = $brd["stateUp"];
		$this->characterID	  = $brd["characterID"];
		$this->placeDepth	  = $brd["placeDepth"];
		$this->placeMatrix    = new MKMatrix();
		$this->placeMatrix->set_matrix_data($brd["placeMatrix"]);

		if($this->buttonType == BUTTON2)
			$this->colorTransform = new MKCxformWithAlpha("", $brd["colorTransform"]);

		if($this->hasFilterList) $this->filterList = new MKfilterList("", $brd["filterList"]);
		if($this->hasBlendMode) $this->BlendMode = $brd["blendMode"];

		$this->buf = substr($this->buf, 0 , $brd["length"]);
	}

	//
	function fetch_assoc(){

		$brd = array();

		$brd["hasBlendMode"]  = $this->hasBlendMode;
		$brd["hasFilterList"] = $this->hasFilterList;
		$brd["buttonType"]	  = $this->buttonType;
		$brd["stateHitTest"]  = $this->stateHitTest;
		$brd["stateDown"]	  = $this->stateDown;
		$brd["stateOver"]	  = $this->stateOver;
		$brd["stateUp"]		  = $this->stateUp;
		$brd["characterID"]	  = $this->characterID;
		$brd["placeDepth"]	  = $this->placeDepth;
		$brd["placeMatrix"]	  = $this->placeMatrix->fetch_assoc();

		if($this->buttonType == BUTTON2)
			$brd["colorTransform"] = $this->colorTransform->fetch_assoc();

		if($this->hasFilterList)
			$brd["filterList"] = $this->filterList->fetch_assoc();

		if($this->hasBlendMode)
			$brd["blendMode"] = $this->blendMode;

		return $brd;
	}

	//
	function get_length(){
		if(!strlen($this->buf))
		$this->set_buttonRecord_data();
		return strlen($this->buf);
	}

	//
	function update_buf(){

		if(!strlen($this->buf))
			return $this->set_buttonRecord_data();

		return $this->buf;
	}
}

/**
 * BUTTONCONDACTION
 */
class MKButtonCondAction {

	var $buf = "";

	var $actionSize;		// UI16 Offset in bytes from start of this
							// field to next
							// BUTTONCONDACTION, or 0
							// if last action

	var $idleToOverDown;	// UB[1] Idle to OverDown
	var $outDownToIdle;		// UB[1] OutDown to Idle
	var $outDownToOverDown;	// UB[1] OutDown to OverDown
	var $overDownToOutDown;	// UB[1] OverDown to OutDown
	var $overDownToOverUp;	// UB[1] OverDown to OverUp
	var $overUpToOverDown;	// UB[1] OverUp to OverDown
	var $overUpToIdle;		// UB[1] OverUp to Idle
	var $idleToOverUp;		// UB[1] Idle to OverUp
	var $keyPress;			// UB[7] SWF 4 or later: key code
							// Otherwise: always 0
							// Valid key codes:
							// 1: left arrow
							// 2: right arrow
							// 3: home
							// 4: end
							// 5: insert
							// 6: delete
							// 8: backspace
							// 13: enter
							// 14: up arrow
							// 15: down arrow
							// 16: page up
							// 17: page down
							// 18: tab
							// 19: escape
							// 32-126: follows ASCII

	var $overDownToIdle;	// UB[1] OverDown to Idle
							// Actions ACTIONRECORD
							// [zero or more]
							// Actions to perform � see the
							// DoAction tag

	var $arObj;

	function MKButtonCondAction($buf = ""){

		$this->buf = $buf;

		if(strlen($buf)){
			$this->get_buttonCondAction_data();
		}
	}

	//
	function set_buttonCondAction_data(){

	}

	//
	function get_buttonCondAction_data(){

		$bcaData = array();
		$bcaData = read_buttonCondAction_header_data(substr($this->buf, 0, 4));

		$bLength = strlen($this->buf);
		$arBuf = substr($this->buf, 4, $bLength - 5);

		$this->actionSize		 = $bcaData["actionSize"];
		$this->idleToOverDown	 = $bcaData["idleToOverDown"];
		$this->outDownToIdle	 = $bcaData["outDownToIdle"];
		$this->outDownToOverDown = $bcaData["outDownToOverDown"];
		$this->overDownToOutDown = $bcaData["overDownToOutDown"];
		$this->overDownToOverUp  = $bcaData["overDownToOverUp"];
		$this->overUpToOverDown  = $bcaData["overUpToOverDown"];
		$this->overUpToIdle		 = $bcaData["overUpToIdle"];
		$this->idleToOverUp		 = $bcaData["idleToOverUp"];
		$this->keyPress			 = $bcaData["keyPress"];
		$this->overDownToIdle	 = $bcaData["overDownToIdle"];

		$this->arObj = new MKActionRecords($arBuf);
	}

	//
	function fetch_assoc(){

		$bcaData = array();

		$bcaData["actionSize"]		  = $this->actionSize;
		$bcaData["idleToOverDown"]	  = $this->idleToOverDown;
		$bcaData["outDownToIdle"]	  = $this->outDownToIdle;
		$bcaData["outDownToOverDown"] = $this->outDownToOverDown;
		$bcaData["overDownToOutDown"] = $this->overDownToOutDown;
		$bcaData["overDownToOverUp"]  = $this->overDownToOverUp;
		$bcaData["overUpToOverDown"]  = $this->overUpToOverDown;
		$bcaData["overUpToIdle"]	  = $this->overUpToIdle;
		$bcaData["idleToOverUp"]	  = $this->idleToOverUp;
		$bcaData["keyPress"]		  = $this->keyPress;
		$bcaData["overDownToIdle"]	  = $this->overDownToIdle;

		return $bcaData;
	}

	//
	function fetch_flasm($indentationLevel = 4){

		$bcaData = $this->fetch_assoc();

		$il = $indentationLevel;
		$ilStr = str_repeat(" ", $il);
		$fStr = "\r\n" .$ilStr ."on ";

		$evtStr = "";

		foreach($bcaData as $k => $v){

			if($k == "actionSize") continue;

			if($v == true || $v > 0){

				if($k == "keyPress"){
					$evtStr .= "keyPress '" .get_keyPress_code($v) ."', ";
				}
				else $evtStr .= $k .", ";
			}
		}

		$evtStr = substr($evtStr, 0, -2);
		$fStr .= $evtStr;

		$fStr .= $this->arObj->fetch_flasm($il + 2);
		$fStr .= $ilStr ."end";
		$fStr .= "\r\n";

		return $fStr;
	}
}

/**
 * defineButtonSound class wrapper
 */
class MKButtonSound extends MKTagHeader {

	// ButtonId;			// UI16 The ID of the button these sounds apply to.
							// alias of itemID

	var $soundChar0 = 0;	// UI16 Sound ID for OverUpToIdle
	var $soundInfo0;		// SOUNDINFO (if ButtonSoundChar0 is nonzero)
							// Sound style for OverUpToIdle
	var $soundChar1 = 0;	// UI16 Sound ID for IdleToOverUp
	var $soundInfo1;		// SOUNDINFO (if ButtonSoundChar1 is nonzero)
							// Sound style for IdleToOverUp
	var $soundChar2 = 0;	// UI16 Sound ID for OverUpToOverDown
	var $soundInfo2; 		// SOUNDINFO (if ButtonSoundChar2 is nonzero)
							// Sound style for OverUpToOverDown
	var $soundChar3 = 0;	// UI16 Sound ID for OverDownToOverUp
	var $soundInfo3;		// SOUNDINFO (if ButtonSoundChar3 is nonzero)
							// Sound style for OverDownToOverUp
	var $nodeName = "buttonSound";

	function MKButtonSound($tagData = "", $buttonID = 1){

		$this->tagData = $tagData;
		$this->itemID = $buttonID;
		$this->tagID = BUTTON_SOUND;

		if(strlen($tagData)){
			parent::MKTagHeader(substr($tagData, 0 ,10));
			$this->get_buttonSound_data();
		}
	}

	//
	function set_buttonID($buttonID) { $this->itemID = $buttonID; }
	function get_buttonID() { return $this->itemID; }

	//
	function set_soundChar0($soundChar0) { $this->soundChar0 = $soundChar0; }
	function get_soundChar0() { return $this->soundChar0; }

	//
	function set_soundInfo0($soundInfo0) { $this->soundInfo0  = $soundInfo0; }
	function get_soundInfo0() { return $this->soundInfo0; }

	//
	function set_soundChar1($soundChar1) { $this->soundChar1 = $soundChar1; }
	function get_soundChar1() { return $this->soundChar1; }

	//
	function set_soundInfo1($soundInfo1) { $this->soundInfo1 = $soundInfo1; }
	function get_soundInfo1() { return $this->soundInfo1; }

	//
	function set_soundChar2($soundChar2) { $this->soundChar2 = $soundChar2; }
	function get_soundChar2() { return $this->soundChar2; }

	//
	function set_soundInfo2($soundInfo2) { $this->ssoundInfo2 = $soundInfo2; }
	function get_soundInfo2() { return $this->soundInfo2; }

	//
	function set_soundChar3($soundChar3) { $this->soundChar3 = $soundChar3; }
	function get_soundChar3() { return $this->oundChar3; }

	//
	function set_soundInfo3($soundInfo3) { $this->ssoundInfo3 = $soundInfo3; }
	function get_soundInfo3() { return $this->soundInfo3; }

	// build buttonSound state
	// soundID: sound for the relevant event
	// eventType: one of these: ROLL_OUT, ROLL_OVER, PRESS, RELEASE
	// soundInfo: a soundInfo object
	function set_sound_event($soundID  = 1, $eventType = ROLL_OVER, $soundInfo = ""){

		if($eventType == ROLL_OUT){
			$this->soundChar0 = $soundID;
			if(get_class($soundInfo) == "MKSoundInfo"){
				$this->soundInfo0 = $soundInfo;
			}
			else if(is_array($soundInfo)){
				$this->soundInfo0 = new MKSoundInfo("", $soundInfo);
			}
			else {
				$this->soundInfo0 = new MKSoundInfo();
			}
		}
		else if($eventType == ROLL_OVER){
			$this->soundChar1 = $soundID;
			if(get_class($soundInfo) == "MKSoundInfo"){
				$this->soundInfo1 = $soundInfo;
			}
			else if(is_array($soundInfo)){
				$this->soundInfo1 = new MKSoundInfo("", $soundInfo);
			}
			else {
				$this->soundInfo1 = new MKSoundInfo();
			}
		}
		else if($eventType == PRESS){
			$this->soundChar2 = $soundID;
			if(get_class($soundInfo) == "MKSoundInfo"){
				$this->soundInfo2 = $soundInfo;
			}
			else if(is_array($soundInfo)){
				$this->soundInfo2 = new MKSoundInfo("", $soundInfo);
			}
			else {
				$this->soundInfo2 = new MKSoundInfo();
			}
		}
		else if($eventType == RELEASE){
			$this->soundChar3 = $soundID;
			if(get_class($soundInfo) == "MKSoundInfo"){
				$this->soundInfo3 = $soundInfo;
			}
			else if(is_array($soundInfo)){
				$this->soundInfo3 = new MKSoundInfo("", $soundInfo);
			}
			else {
				$this->soundInfo3 = new MKSoundInfo();
			}
		}
	}

	//
	function set_buttonSound_data($bsd = array()){

		if(count($bsd)) $this->get_buttonSsound_data($bsd);
		else $bsd = $this->fetch_assoc();

		$this->tagData = write_defineButtonSound_data($bsd);
		return $this->tagData;
	}

	function get_buttonSound_data($bsd = array()){

		if(!count($bsd)) $bsd = read_defineButtonSound_data($this->tagData);
		//else $this->

		$this->itemID	  = $bsd["itemID"];

		$this->soundChar0 = $bsd["soundChar0"];
		if($this->soundChar0)
			$this->soundInfo0 = new MKSoundInfo("", $bsd["soundInfo0"]);

		$this->soundChar1 = $bsd["soundChar1"];
		if($this->soundChar1)
			$this->soundInfo1 = new MKSoundInfo("", $bsd["soundInfo1"]);

		$this->soundChar2 = $bsd["soundChar2"];
		if($this->soundChar2)
			$this->soundInfo2 = new MKSoundInfo("", $bsd["soundInfo2"]);

		$this->soundChar3 = $bsd["soundChar3"];
		if($this->soundChar3)
			$this->soundInfo3 = new MKSoundInfo("", $bsd["soundInfo3"]);

		return $bsd;

	}

	//
	function fetch_assoc(){

		$bsd = array();

		$bsd["itemID"] = $this->itemID;
		$bsd["soundChar0"] = $this->soundChar0;
		if($this->soundChar0)
			$bsd["soundInfo0"] = $this->soundInfo0->fetch_assoc();

		$bsd["soundChar1"] = $this->soundChar1;
		if($this->soundChar1)
			$bsd["soundInfo1"] = $this->soundInfo1->fetch_assoc();

		$bsd["soundChar2"] = $this->soundChar2;
		if($this->soundChar2)
			$bsd["soundInfo2"] = $this->soundInfo2->fetch_assoc();

		$bsd["soundChar3"] = $this->soundChar3;
		if($this->soundChar3)
			$bsd["soundInfo3"] = $this->soundInfo3->fetch_assoc();

		return $bsd;
	}

	//
	function fetch_xml($includeHeader = true, $tabLevel = 0, $includeHexData = false, $nodeName = "buttonSound"){

		$xmlStr = $includeHeader ? XML_HEADER : "";
		$pfx = get_xml_indent_row(++$tabLevel);

		$xmlStr .= $pfx ."<" .$nodeName ." ";

		$xmlStr .= "useButtonID=\"";
		$xmlStr .= $this->itemID ."\" ";

		$xmlStr .= "tagSize=\"";
		$xmlStr .= strlen($this->tagData) ."\" >";

		$pfx = get_xml_indent_row(++$tabLevel);

		if($this->soundChar0){
			$xmlStr .= $pfx ."<rollOut soundID=\"";
			$xmlStr .= $this->soundChar0 ."\"";
			$siStr = $this->soundInfo0->fetch_xml(false, $pfx);

			if(strlen($siStr)) {
				$xmlStr .= ">";
				$xml .= $siStr;
				$xmlStr .= "</rollOut>";
			}
			else $xmlStr .= " />";

			$xmlStr .= "\r\n";
		}
		if($this->soundChar1){
			$xmlStr .= $pfx ."<rollOver soundID=\"";
			$xmlStr .= $this->soundChar1 ."\"";
			$siStr = $this->soundInfo1->fetch_xml(false, $pfx);

			if(strlen($siStr)) {
				$xmlStr .= ">";
				$xmlStr .= $siStr;
				$xmlStr .= "</rollOver>";
			}
			else $xmlStr .= " />";

			$xmlStr .= "\r\n";
		}
		if($this->soundChar2){
			$xmlStr .= $pfx ."<onPress soundID=\"";
			$xmlStr .= $this->soundChar2 ."\"";

			$siStr = $this->soundInfo2->fetch_xml(false, $pfx);

			if(strlen($siStr)) {
				$xmlStr .= ">";
				$xml .= $siStr;
				$xmlStr .= "</onPress>";
			}
			else $xmlStr .= " />";

			$xmlStr .= "\r\n";
		}
		if($this->soundChar3){
			$xmlStr .= $pfx ."<onRelease soundID=\"";
			$xmlStr .= $this->soundChar3 ."\"";

			$siStr = $this->soundInfo3->fetch_xml(false, $pfx);

			if(strlen($siStr)) {
				$xmlStr .= ">";
				$xml .= $siStr;
				$xmlStr .= "</onRelease>";
			}
			else $xmlStr .= " />";

			$xmlStr .= "\r\n";
		}

		$pfx = get_xml_indent_row(--$tabLevel);

		$xmlStr .= $pfx ."</" .$nodeName .">";
		return $xmlStr;
	}

	//
	function update_tagData(){
		return $this->set_buttonSound_data();
	}
}

?>
